package com.luo.chengrui.module.sa.service.datapermission;

import cn.hutool.core.util.StrUtil;
import com.luo.chengrui.module.sa.dal.dataobject.datapermission.DataPermissionDefineDataDO;
import com.luo.chengrui.module.sa.dal.mysql.datapermission.DataPermissionDefineDataMapper;
import com.luo.chengrui.module.sa.dal.redis.RedisKeyConstants;
import com.luo.chengrui.module.sa.service.datapermission.DataPermissionDefineService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.*;

import com.luo.chengrui.module.sa.controller.admin.datapermission.vo.*;
import com.luo.chengrui.module.sa.dal.dataobject.datapermission.DataPermissionDefineDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import com.luo.chengrui.module.sa.convert.datapermission.DataPermissionDefineConvert;
import com.luo.chengrui.module.sa.dal.mysql.datapermission.DataPermissionDefineMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.luo.chengrui.module.sa.enums.ErrorCodeConstants.*;

/**
 * 用来定义哪些业务表用来做权限控制，如部门表、费用科目、项目表。一般用来控制权限的都是基础数据表。 Service 实现类
 *
 * @author luodz
 */
@Service
@Validated
public class DataPermissionDefineServiceImpl implements DataPermissionDefineService {

    @Resource
    private DataPermissionDefineMapper dataPermissionDefineMapper;
    @Resource
    private DataPermissionDefineDataMapper dataPermissionDefineDataMapper;

    @Override
    public String createDataPermissionDefine(DataPermissionDefineCreateReqVO createReqVO) {
        createReqVO.setVersion(System.currentTimeMillis());
        // 插入
        DataPermissionDefineDO dataPermissionDefine = DataPermissionDefineConvert.INSTANCE.convert(createReqVO);
        validateTableName(dataPermissionDefine);
        dataPermissionDefineMapper.insert(dataPermissionDefine);
        // 返回
        return dataPermissionDefine.getId();
    }

    @Override
    public void updateDataPermissionDefine(DataPermissionDefineUpdateReqVO updateReqVO) {
        updateReqVO.setVersion(System.currentTimeMillis());
        // 校验存在
        validateDataPermissionDefineExists(updateReqVO.getId());
        // 更新
        DataPermissionDefineDO updateObj = DataPermissionDefineConvert.INSTANCE.convert(updateReqVO);
        validateTableName(updateObj);
        dataPermissionDefineMapper.updateById(updateObj);
    }

    @Override
    public void deleteDataPermissionDefine(String id) {
        // 校验存在
        validateDataPermissionDefineExists(id);
        // 删除
        dataPermissionDefineMapper.deleteById(id);
    }

    private void validateDataPermissionDefineExists(String id) {
        if (dataPermissionDefineMapper.selectById(id) == null) {
            throw exception(DATA_PERMISSION_DEFINE_NOT_EXISTS);
        }
    }

    private void validateTableName(DataPermissionDefineDO defineDO) {
        DataPermissionDefineDO dataPermissionDefineDO = dataPermissionDefineMapper.selectOne(DataPermissionDefineDO::getTableName, defineDO.getTableName());
        if (dataPermissionDefineDO == null) {
            return;
        }
        if (defineDO.getId() == null || !Objects.equals(defineDO.getId(), dataPermissionDefineDO.getId())) {
            throw exception(DATA_PERMISSION_DEFINE_TABLE_NAME_EXISTS);
        }
    }

    @Override
    public DataPermissionDefineDO getDataPermissionDefine(String id) {
        return dataPermissionDefineMapper.selectById(id);
    }

    @Override
    public List<DataPermissionDefineDO> getDataPermissionDefineList(Collection<String> ids) {
        return dataPermissionDefineMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<DataPermissionDefineDO> getDataPermissionDefinePage(DataPermissionDefinePageReqVO pageReqVO) {
        return dataPermissionDefineMapper.selectPage(pageReqVO);
    }

    @Override
    public List<DataPermissionDefineDO> getDataPermissionDefineList(DataPermissionDefineExportReqVO exportReqVO) {
        return dataPermissionDefineMapper.selectList(exportReqVO);
    }

    @Override
    public List<DataPermissionDefineDO> getDataPermissionDefineAllList() {
        return dataPermissionDefineMapper.selectList(new DataPermissionDefineDO());
    }

    @Override
//    @Cacheable(value = RedisKeyConstants.SA_PERMISSION_DEFINE_DATA, key = "#defineId")
    public List<DataPermissionDefineDataDO> getDataPermissionDefineAllData(String defineId) {
        // 校验存在
        DataPermissionDefineDO dataPermissionDefineDO = dataPermissionDefineMapper.selectById(defineId);
        if (dataPermissionDefineDO == null) {
            throw exception(DATA_PERMISSION_DEFINE_NOT_EXISTS);
        }

        if(StrUtil.isNotEmpty(dataPermissionDefineDO.getSqlScript())){
            return dataPermissionDefineDataMapper.executeSelectSqlScript(dataPermissionDefineDO.getSqlScript());
        }else{
            return dataPermissionDefineDataMapper.selectDefineData(dataPermissionDefineDO);
        }
    }
}
